﻿using EasyAdmin.Application.Contracts.Systems.Apis;
using EasyAdmin.Application.Systems;
using EasyAdmin.DatabaseAccessor.SqlSugar.Setting;
using EasyAdmin.Web.ApiCollectors;
using EasyAdmin.Web.Authorizations;
using EasyAdmin.Web.EasySwagger;
using EasyAdmin.Web.Middlewares;
using EasyCore.App;
using EasyCore.Auth;
using EasyCore.Caching;
using EasyCore.Core;
using EasyCore.DataValidation;
using EasyCore.DependencyInjection;
using EasyCore.EndpointAudits;
using EasyCore.Extensions;
using EasyCore.Logging;
using EasyCore.ObjectMapper;
using EasyCore.UnifyResult;
using EasyCore.UnitOfWork;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using Masuit.Tools.Systems.Text.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Text.Unicode;
using Yitter.IdGenerator;
using EasyAdmin.Application;

namespace EasyAdmin.Web.Extensions
{
    public static class EasyAdminWebExtensions
    {
        public static void AddEasyWebCore(this WebApplicationBuilder builder)
        {
            //设置API全局构造器
            EasyApp.ApplicationBuilder = builder;

            //添加JSON文件
            builder.AddJsonFiles();  
            //添加httpContextAccessor
            builder.Services.AddHttpContextAccessor();
            //增加API异常处理器
            builder.Services.AddApiExceptionHandler();
            //增加API统一结果处理器
            builder.Services.AddUnifyResult();
            //增加工作单元处理器
            builder.Services.AddUnitOfWork();
            //收集所有APIs信息
            builder.Services.AddEndpointsApiExplorer();//添加终端API浏览器
            //添加添加验证，并屏蔽.net自带的验证器
            builder.Services.AddEasyDataValidation(options => {
                options.DisableBuiltInModelValidation = false;
            });//新增参数验证器
            //添加终结点数据重复性提交判断或是否终结点访问日志保存
            builder.Services.AddEndpointAudits(options => {
                options.OverrideEndpointAuditHandlerWith<EndpointLogAppService>();
            });
            //动态添加依赖类型(添加系统的依赖注入)
            builder.Services.AddInjectionTypes();
            //动态添加对象映射
            builder.Services.AddObjectMapper();
            //添加JWT认证
            builder.Services.AddJwtAuthentication();
            //添加日志 
            builder.Services.AddMoreLogging();
            //添加缓存服务   
            builder.Services.AddEasyCache();
            // 配置雪花Id算法机器码
            YitIdHelper.SetIdGenerator(new IdGeneratorOptions
            {
                WorkerId = 1// 取值范围0~63,默认1
            });
            //增加API收集器
            builder.Services.AddApiCollectorServices(options =>
            {
                var xmlFilename = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
                options.xmlFilePath = Path.Combine(AppContext.BaseDirectory, xmlFilename);
            });
            //ip搜索
            builder.Services.AddBrowserDetection();
            builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, "SearcherResource", "ip", "ip2region.xdb")));            
            //配置数据库连接
            var sqlSugarSettings = builder.Configuration.Get<List<SqlSugarSettings>>("SqlSugarSettings:ConnectionStrings");//从配置文件中读取数据库配置信息
            builder.Services.AddSqlSugar(sqlSugarSettings); //数据库配置
                                                            

            builder.Services.AddEasySwagger();//添加Swagger服务

            
            




            /*
   
            */
            builder.Services.AddIpRateLimit();

            //模型绑定错误信息中文化
            builder.Services.AddControllers(options =>
            {

                ////A value for the ‘{0}’ parameter or property was not provided
                //options.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor((x) => $"未 提供'{x}' 参数或属性的值");
                ////A value is required
                //options.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(() => $"需要一个值");
                ////A non-empty request body is required
                //options.ModelBindingMessageProvider.SetMissingRequestBodyRequiredValueAccessor(() => $"需要非空的请求正文");
                ////The value ‘{0}’ is invalid
                //options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor((x) => $"值'{x}'无效，不能为Null");
                ////The value ‘{0}’ is not valid for {1}.
                //options.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor((x, y) => $"值'{x}'对参数'{y}'无效");
                ////The value ‘{0}’ is not valid.
                //options.ModelBindingMessageProvider.SetNonPropertyAttemptedValueIsInvalidAccessor((x) => $"值'{x}'无效");
                ////The supplied value is invalid for {0}.
                //options.ModelBindingMessageProvider.SetUnknownValueIsInvalidAccessor((x) => $"提供的值对参数'{x}'无效");
                ////The supplied value is invalid.
                //options.ModelBindingMessageProvider.SetNonPropertyUnknownValueIsInvalidAccessor(() => $"提供的值无效");
                ////The value ‘{0}’ is invalid.
                //options.ModelBindingMessageProvider.SetValueIsInvalidAccessor((x) => $"值'{x}'无效");
                ////The field {0} must be a number
                //options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor((x) => $"字段'{x}' 必须是数字");
                ////The field must be a number.
                //options.ModelBindingMessageProvider.SetNonPropertyValueMustBeANumberAccessor(() => $"字段必须是数字");
            }).AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.WriteIndented = true;
                options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                //设置时间格式
                options.JsonSerializerOptions.Converters.Add(new DateTimeJsonConverter());
                //options.JsonSerializerOptions.Converters.Add(new DateTimeNullableConverter());
                ////设置bool获取格式
                //options.JsonSerializerOptions.Converters.Add(new BooleanJsonConverter());
                ////设置Decimal获取格式
                //options.JsonSerializerOptions.Converters.Add(new DecimalJsonConverter());
                //////设置数字
                //options.JsonSerializerOptions.Converters.Add(new IntJsonConverter());
                //options.JsonSerializerOptions.PropertyNamingPolicy = new UpperFirstCaseNamingPolicy();
                options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
            });
  
       



            //builder.Services.AddScoped<IValidator<CreateUpdateBookDto>, CreateUpdateBookDtoValidator>();
            //添加跨域
            //builder.Services.AddCors(option =>
            //option.AddPolicy("cors", policy => policy.AllowAnyHeader().AllowAnyMethod().AllowCredentials().AllowAnyOrigin()));

            //builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, AppAuthorizationHandler>());
            //builder.Services.AddTransient<IAuthorizationPolicyProvider, AppAuthorizationPolicyProvider>();


            /*
            //----------------------------------------------------------------------------------授权
            builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, MinimumAgeAuthorizationHandler>()); //对应的MinimumAgeRequirement
            builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, MinimumAgeAnotherAuthorizationHandler>()); //对应的MinimumAgeRequirement
            builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IAuthorizationHandler, MultiRequirementsAuthorizationHandler>()); //一个多处理对应多个Requirement
            builder.Services.AddTransient<IAuthorizationPolicyProvider, AppAuthorizationPolicyProvider>();
            
            builder.Services.AddAuthorization(options =>
            {
                //options.InvokeHandlersAfterFailure = true;//授权失败后,是否继续执行相处授权处理器
                options.AddPolicy("AtLeast18Age", policy => policy.Requirements.Add(new MinimumAgeRequirement(18)));//增加授权处理器,对应两个授权处理器
                options.AddPolicy("Custom1Requirement", policy => policy.Requirements.Add(new Custom1Requirement()));//多个Requiremen对应一个授权处理器
                options.AddPolicy("Custom2Requirement", policy => policy.Requirements.Add(new Custom2Requirement()));//多个Requiremen对应一个授权处理器
                                                                                                                     // 仅要求具有声明 Rank
                options.AddPolicy("RankClaim", policy => policy.RequireClaim("Rank"));
                // 要求具有声明 Rank，且值为 P3
                options.AddPolicy("RankClaimP3", policy => policy.RequireClaim("Rank", "P3"));
                // 要求具有声明 Rank，且值为 M3
                options.AddPolicy("RankClaimM3", policy => policy.RequireClaim("Rank", "M3"));
                // 要求具有声明 Rank，且值为 P3 或 M3
                options.AddPolicy("RankClaimP3OrM3", policy => policy.RequireClaim("Rank", "P3", "M3"));
                // 要求具有声明 Rank，且同时具有两个值：P3 和 M3
                options.AddPolicy("RankClaimP3AndM3", policy => policy.RequireClaim("Rank", "P3").RequireClaim("Rank", "M3"));
                // 复杂声明
                options.AddPolicy("ComplexClaim", policy => policy.RequireAssertion(context =>
                    context.User.HasClaim(c => (c.Type == "Rank" || c.Type == "Name") && c.Issuer == "Issuer")));
            });

            */
        }


        //使用web的内核
        public static void UseEasyWebCore(this WebApplication app)
        {
            EasyApp.Root = app.Services; //获得全局的根服务容器
            app.InitDatabase(); //初始化数据库
            app.UseEasyCache();//缓存初始化操作
                               //app.InitDatabase(); //初始化数据库
            app.UseObjectMapper(); //DTO与实体之间相互转换实现依赖注入
            //收集并保存接口
            app.CollectApis();
            app.UseStaticFiles();//添加静态文件的支持
            if (app.Environment.IsDevelopment())
            {
                app.UseEasySwagger();//开启添加Swagger服务
            }
            app.UseMiddleware<ApplicationMiddleware>(); //实现当前请求相关配置:包括当前请求的服务范围、当前用户相关信息
            app.UseMiddleware<ExceptionHandlerMiddleware>(); //统一结果中间件
            app.UseCors("cors"); //添加跨域中间件
            app.UseAuthentication();//解析当前用户的身份标识  
            //判断当前终节点是否使用了认证及角色策略，然后校验令牌是否有效
            app.UseAuthorization();
            app.UseIpRateLimit();
            app.MapControllers();
            app.Run();
        }
    }
}
